/**
 ******************************************************************************
  @file  stl_test_pc.S
 verbatim
  Change Logs:
  Date             Author          Notes
  2024-10-31       CDT             First version
 endverbatim
 *****************************************************************************
 * Copyright (C) 2022-2025, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

.syntax     unified
.arch       armv7e-m
.cpu        cortex-m4
.thumb

/*
 * function    : uint32_t STL_PcTest(void);
 * Description : Test PC
 * Input       : None.
 * Output      : Perform routine when detect failure at set of self test cases
 * Return      : STL_OK (=0):test pass; STL_ERR (=1):test fail;
 * WARNING     : all registers destroyed when exiting this function (including
 *               preserved registers R4 to R11) and excluding stack point R13)
 */
.align      2
.global STL_PcTest
.type STL_PcTest, %function
STL_PcTest:
            PUSH {R4-R7}            /* Save registers */
            MOVS R0, #0
            MOVS R1, #0             /* clr R0,R1 */
            MOV  R3, LR

_subroutine_1:
            LDR R0, =_return_pc_test_addr_1
            BL  _return_pc_test_addr_1
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_2
            B _pc_test_fail

_subroutine_2:
            LDR R0, =_return_pc_test_addr_2
            BL  _return_pc_test_addr_2
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_3
            B _pc_test_fail

_subroutine_3:
            LDR R0, =_return_pc_test_addr_3
            BL  _return_pc_test_addr_3
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_4
            B _pc_test_fail

_subroutine_4:
            LDR R0, =_return_pc_test_addr_4
            BL  _return_pc_test_addr_4
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_5
            B _pc_test_fail

_subroutine_5:
            LDR R0, =_return_pc_test_addr_5
            BL  _return_pc_test_addr_5
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_6
            B _pc_test_fail

_subroutine_6:
            LDR R0, =_return_pc_test_addr_6
            BL  _return_pc_test_addr_6
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_7
            B _pc_test_fail

_subroutine_7:
            LDR R0, =_return_pc_test_addr_7
            BL  _return_pc_test_addr_7
            CMP R0, R1              /* verify return address? */
            BEQ _subroutine_8
            B _pc_test_fail

_subroutine_8:
            LDR R0, =_return_pc_test_addr_8
            BL  _return_pc_test_addr_8
            CMP R0, R1              /* verify return address? */
            BEQ _pc_test_pass
            B _pc_test_fail

_pc_test_fail:
            /* when test fail, R0 will hold value 1 */
            MOVS R0, #0x1           /* STL_ERR */
            B _pc_test_exit

_pc_test_pass:
            /* when test pass, R0 will hold value 0 */
            MOVS R0, #0x0           /* STL_OK */
            B _pc_test_exit

_pc_test_exit:
            POP {R4-R7}             /* Restore registers */
            BX R3                   /* return */

_return_pc_test_addr_1:
            LDR R1, =_return_pc_test_addr_1     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_2:
            LDR R1, =_return_pc_test_addr_2     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_3:
            LDR R1, =_return_pc_test_addr_3     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_4:
            LDR R1, =_return_pc_test_addr_4     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_5:
            LDR R1, =_return_pc_test_addr_5     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_6:
            LDR R1, =_return_pc_test_addr_6     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_7:
            LDR R1, =_return_pc_test_addr_7     /* store subroutine address in R1 */
            BX LR

_return_pc_test_addr_8:
            LDR R1, =_return_pc_test_addr_8     /* store subroutine address in R1 */
            BX LR
